<template>
  <div class="asset-quality-audit-view">
    <div class="content-wrapper">
      <!-- 第一行：核心仪表盘 -->
      <div class="section section-dashboard">
        <div class="dashboard-row">
          <!-- KRI Card 1: 核心趋势 (60% 宽度) -->
          <div class="kri-card kri-card-large">
            <div class="card-header">
              <h3>核心趋势</h3>
              <span class="time-label">过去24个月</span>
            </div>
            <div class="card-body">
              <div class="indicators-group">
                <div class="indicator-mini">
                  <span class="label">不良贷款率</span>
                  <span class="value text-danger">{{ badLoanRate.toFixed(2) }}<span class="unit">%</span></span>
                  <span class="change" :class="badLoanRateChange >= 0 ? 'positive' : 'negative'">
                    {{ badLoanRateChange >= 0 ? '+' : '' }}{{ badLoanRateChange.toFixed(2) }}%
                  </span>
                </div>
                <div class="indicator-mini">
                  <span class="label">不良贷款余额</span>
                  <span class="value text-danger">{{ (badLoanBalance / 10000 / 10000).toFixed(2) }}<span class="unit">亿</span></span>
                  <span class="change" :class="badLoanBalanceChange >= 0 ? 'positive' : 'negative'">
                    {{ badLoanBalanceChange >= 0 ? '+' : '' }}{{ (badLoanBalanceChange / 10000 / 10000).toFixed(2) }}亿
                  </span>
                </div>
                <div class="indicator-mini">
                  <span class="label">拨备覆盖率</span>
                  <span class="value text-success">{{ provisionCoverageRatio.toFixed(2) }}<span class="unit">%</span></span>
                  <span class="change" :class="provisionCoverageRatioChange >= 0 ? 'positive' : 'negative'">
                    {{ provisionCoverageRatioChange >= 0 ? '+' : '' }}{{ provisionCoverageRatioChange.toFixed(2) }}%
                  </span>
                </div>
              </div>
              <div class="trend-chart-placeholder">
                <div v-if="isLoading" class="chart-mock">
                  <div class="loading-spinner">⏳ 数据加载中...</div>
                </div>
                <div v-else-if="error" class="chart-mock">
                  <div class="error-message">❌ 数据加载失败: {{ error.message }}</div>
                </div>
                <div v-else ref="trendChartRef" class="trend-chart"></div>
              </div>
            </div>
          </div>
          
          <!-- KRI Card 2: 风险真实性 (40% 宽度) -->
          <div class="kri-card kri-card-medium">
            <div class="card-header">
              <h3>风险真实性</h3>
              <span class="time-label">当前</span>
            </div>
            <div class="card-body card-body-center">
              <div class="overdue-indicators">
                <!-- 逾期60天占比 -->
                <div class="overdue-item">
                  <div class="overdue-gauge">
                    <div class="gauge-value" :class="overdue60RatioClass">
                      {{ overdue60Ratio.toFixed(2) }}<span class="unit">%</span>
                    </div>
                    <div class="gauge-arc">
                      <svg width="160" height="100" viewBox="0 0 160 100">
                        <path d="M 20 80 A 60 60 0 0 1 140 80" 
                              stroke="#1a3a52" 
                              stroke-width="16" 
                              fill="none"/>
                        <path d="M 20 80 A 60 60 0 0 1 140 80" 
                              :stroke="overdue60Ratio >= 100 ? '#ff4d4f' : (overdue60Ratio >= 90 ? '#faad14' : '#52c41a')" 
                              stroke-width="16" 
                              fill="none"
                              :stroke-dasharray="`${overdue60Ratio * 1.88} 500`"
                              stroke-linecap="round"/>
                      </svg>
                    </div>
                  </div>
                  <div class="overdue-label">
                    <div class="label-title">逾期60天占比</div>
                    <div class="label-desc" :class="overdue60RatioClass">
                      {{ overdue60Ratio >= 100 ? '⚠️ 超标' : (overdue60Ratio >= 90 ? '⚡ 预警' : '✓ 合规') }}
                    </div>
                  </div>
                </div>
                
                <!-- 逾期90天占比 -->
                <div class="overdue-item">
                  <div class="overdue-gauge">
                    <div class="gauge-value" :class="overdue90RatioClass">
                      {{ overdue90Ratio.toFixed(2) }}<span class="unit">%</span>
                    </div>
                    <div class="gauge-arc">
                      <svg width="160" height="100" viewBox="0 0 160 100">
                        <path d="M 20 80 A 60 60 0 0 1 140 80" 
                              stroke="#1a3a52" 
                              stroke-width="16" 
                              fill="none"/>
                        <path d="M 20 80 A 60 60 0 0 1 140 80" 
                              :stroke="overdue90Ratio >= 100 ? '#ff4d4f' : (overdue90Ratio >= 90 ? '#faad14' : '#52c41a')" 
                              stroke-width="16" 
                              fill="none"
                              :stroke-dasharray="`${overdue90Ratio * 1.88} 500`"
                              stroke-linecap="round"/>
                      </svg>
                    </div>
                  </div>
                  <div class="overdue-label">
                    <div class="label-title">逾期90天占比</div>
                    <div class="label-desc" :class="overdue90RatioClass">
                      {{ overdue90Ratio >= 100 ? '⚠️ 超标' : (overdue90Ratio >= 90 ? '⚡ 预警' : '✓ 合规') }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 第二行：风险源下钻地图（全宽） -->
      <div class="section section-risk-map">
        <div class="box">
          <div class="tit">
            <span>风险源下钻地图</span>
          </div>
          
          <!-- 选项卡 -->
          <div class="tabs-container">
                <div class="tabs-nav">
                  <button 
                    class="tab-btn" 
                    :class="{ active: activeTab === 'branch' }"
                    @click="activeTab = 'branch'"
                  >
                    按经办机构
                  </button>
                  <button 
                    class="tab-btn" 
                    :class="{ active: activeTab === 'industry' }"
                    @click="activeTab = 'industry'"
                  >
                    按贷款行业
                  </button>
                  <button 
                    class="tab-btn" 
                    :class="{ active: activeTab === 'businessLine' }"
                    @click="activeTab = 'businessLine'"
                  >
                    按业务条线
                  </button>
                </div>
                
                <!-- Tab 内容 -->
                <div class="tab-content">
                  <!-- 按经办机构 -->
                  <div v-show="activeTab === 'branch'" class="tab-pane">
                    <div class="treemap-container" ref="branchTreemapRef"></div>
                  </div>
                  
                  <!-- 按贷款行业 -->
                  <div v-show="activeTab === 'industry'" class="tab-pane">
                    <div class="treemap-container" ref="industryTreemapRef"></div>
                  </div>
                  
                  <!-- 按业务条线 -->
                  <div v-show="activeTab === 'businessLine'" class="tab-pane">
                    <div class="treemap-container" ref="businessLineTreemapRef"></div>
                  </div>
                </div>
          </div>
        </div>
      </div>
      
      <!-- 第三行：未来风险预警（全宽） -->
      <div class="section section-warning">
        <div class="box">
          <div class="tit">
            <span>未来风险预警</span>
          </div>
          
          <div class="warning-row">
            <!-- 后备军规模 -->
            <div class="warning-chart-card">
              <div class="chart-title">
                <span>"后备军"规模</span>
                <span class="chart-subtitle">关注类占比</span>
              </div>
              <div class="chart-value">
                <span class="value-large">{{ attentionLoanRatio.toFixed(2) }}<span class="unit">%</span></span>
                <span class="value-change" :class="attentionLoanRatioChange >= 0 ? 'positive' : 'negative'">
                  {{ attentionLoanRatioChange >= 0 ? '+' : '' }}{{ attentionLoanRatioChange.toFixed(2) }}%
                </span>
              </div>
              <div class="mini-chart-placeholder">
                <div ref="attentionLoanRatioChartRef" class="mini-chart"></div>
              </div>
            </div>
            
            <!-- 恶化速度 -->
            <div class="warning-chart-card">
              <div class="chart-title">
                <span>"恶化速度"</span>
                <span class="chart-subtitle">关注类迁徙率</span>
              </div>
              <div class="chart-value">
                <span class="value-large">{{ migrationRate.toFixed(2) }}<span class="unit">%</span></span>
                <span class="value-change" :class="migrationRateChange >= 0 ? 'positive' : 'negative'">
                  {{ migrationRateChange >= 0 ? '+' : '' }}{{ migrationRateChange.toFixed(2) }}%
                </span>
              </div>
              <div class="mini-chart-placeholder">
                <div ref="migrationRateChartRef" class="mini-chart"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 新增：前十大不良贷款户 -->
      <div class="section section-top-customers">
        <div class="box">
          <div class="tit">
            <span>前十大不良贷款户</span>
          </div>
          
          <div class="top-customers-content">
            <div v-if="isLoadingTopCustomers" class="loading-container">
              <div class="loading-spinner">⏳ 加载数据中...</div>
            </div>
            <div v-else-if="topBadLoanCustomers.length === 0" class="empty-container">
              <div class="empty-message">暂无数据</div>
            </div>
            <div v-else class="treemap-container" ref="topCustomersTreemapRef"></div>
          </div>
        </div>
      </div>
      
      <!-- 第四行：根源诊断 -->
      <!-- <div class="section section-root-cause">
        <div class="box">
          <div class="tit">
            <span>根源诊断 - 新老贷款质量对比 (Vintage Analysis)</span>
          </div>
          <div class="vintage-analysis">
            <div class="chart-area-large">
              <div ref="vintageChartRef" class="vintage-chart"></div>
              <div class="chart-insight">
                <span class="insight-icon">💡</span>
                <span class="insight-text">洞察：贷款账龄越长，不良贷款占比越高。3年以上账龄的不良贷款占比最高，需重点关注。</span>
              </div>
            </div>
          </div>
        </div>
      </div> -->
    </div>
    
    <!-- 客户详情弹窗 -->
    <div v-if="showDetailDialog" class="detail-dialog-overlay" @click="showDetailDialog = false">
      <div class="detail-dialog" @click.stop>
        <div class="dialog-header">
          <h3>{{ selectedCustomer?.name }} - 借据详情</h3>
          <button class="close-btn" @click="showDetailDialog = false">✕</button>
        </div>
        <div class="dialog-body">
          <div class="customer-summary">
            <div class="summary-item">
              <span class="label">不良贷款总额:</span>
              <span class="value">{{ (selectedCustomer?.value / 10000 / 10000).toFixed(2) }} 亿元</span>
            </div>
            <div class="summary-item">
              <span class="label">借据数量:</span>
              <span class="value">{{ selectedCustomer?.loanCount }} 笔</span>
            </div>
          </div>
          
          <div class="loans-table">
            <table>
              <thead>
                <tr>
                  <th>序号</th>
                  <th>借据号/卡号</th>
                  <th>合同编号</th>
                  <th>产品类型</th>
                  <th>五级分类</th>
                  <th>贷款金额(万元)</th>
                  <th>贷款余额(万元)</th>
                  <th>贷款余额(元)</th>
                  <th>放款日期</th>
                  <th>到期日期</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(loan, index) in selectedCustomer?.loans" :key="index">
                  <td>{{ index + 1 }}</td>
                  <td class="text-highlight">{{ loan.loanId || loan.cardNo || '-' }}</td>
                  <td>{{ loan.contractNo || '-' }}</td>
                  <td>{{ loan.productName || '-' }}</td>
                  <td>
                    <span class="risk-badge" :class="getRiskClass(loan.riskLevel)">
                      {{ getRiskLabel(loan.riskLevel) }}
                    </span>
                  </td>
                  <td class="text-right">{{ (loan.loanAmount / 10000).toFixed(2) }}</td>
                  <td class="text-right text-amount">{{ (loan.balance / 10000).toFixed(2) }}</td>
                  <td class="text-right">{{ loan.balance.toLocaleString('zh-CN', { maximumFractionDigits: 2 }) }}</td>
                  <td>{{ loan.loanDate || '-' }}</td>
                  <td>{{ loan.dueDate || '-' }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 新增：支行不良贷款率动态排序图 -->
    <div class="section section-npl-race">
      <div class="box">
        <div class="tit">
          <span>支行不良贷款率动态排行</span>
          <span class="tit-subtitle">最近12个月趋势</span>
        </div>
        
        <div class="npl-race-content">
          <div v-if="isLoadingNPLRace" class="loading-container">
            <div class="loading-spinner">⏳ 加载数据中...</div>
          </div>
          <div v-else-if="nplRaceData.length === 0" class="empty-container">
            <div class="empty-message">暂无数据</div>
          </div>
          <div v-else>
            <div class="race-controls">
              <button @click="toggleRaceAnimation" class="race-btn">
                {{ isRacePlaying ? '⏸️ 暂停' : '▶️ 播放' }}
              </button>
              <button @click="resetRaceAnimation" class="race-btn">🔄 重置</button>
              <span class="race-speed">
                速度：
                <select v-model="raceSpeed" @change="updateRaceSpeed">
                  <option value="500">快速</option>
                  <option value="1000">正常</option>
                  <option value="2000">慢速</option>
                </select>
              </span>
            </div>
            <div ref="nplRaceChartRef" class="npl-race-chart"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch, nextTick, computed } from 'vue'
import * as echarts from 'echarts'
import { useAssetQuality } from '../composables/useAssetQuality.js'
import { useAssetQualityStore } from '../stores/assetQualityStore.js'

// 使用资产质量数据
const { 
  isLoading, 
  error, 
  assetData, 
  fetchAssetQualityData,
  fetchBranchBadLoanData,
  fetchIndustryBadLoanData,
  fetchBusinessLineBadLoanData,
  fetchVintageAnalysisData,
  fetchTopBadLoanCustomers,  // 新增：获取前十大不良贷款户
  fetchBranchNPLRateTimeSeries,  // 新增：获取支行不良贷款率时序数据
  getLatestValue,
  getChange,
  setAssetData  // 新增：用于从缓存恢复数据
} = useAssetQuality()

// 使用资产质量存储
const assetQualityStore = useAssetQualityStore()

// 机构号与名称的映射关系
const ORG_NAME_MAP = {
  '01000': '中堂支行',
  '02000': '望牛墩支行',
  '03000': '道滘支行',
  '04000': '洪梅支行',
  '05000': '麻涌支行',
  '06000': '万江支行',
  '07000': '虎门支行',
  '08000': '长安支行',
  '09000': '厚街支行',
  '10000': '沙田支行',
  '11000': '南城支行',
  '12000': '东城支行',
  '13000': '寮步支行',
  '14000': '大岭山支行',
  '15000': '大朗支行',
  '16000': '黄江支行',
  '17000': '樟木头支行',
  '18000': '清溪支行',
  '19000': '塘厦支行',
  '20000': '凤岗支行',
  '21000': '谢岗支行',
  '22000': '常平支行',
  '23000': '桥头支行',
  '24000': '横沥支行',
  '25000': '东坑支行',
  '26000': '企石支行',
  '27000': '石排支行',
  '28000': '茶山支行',
  '29000': '石碣支行',
  '30000': '高埗支行',
  '31000': '东联支行',
  '32000': '石龙支行',
  '33000': '松山湖科技支行',
  '38000': '中心支行',
  '50000': '惠州支行',
  '51000': '清新支行',
  '52000': '南沙分行',
  '53000': '横琴分行',
  '55000': '佛山分行',
  '81000': '信用卡中心',
  '82000': '广州分行'
}

// 根据机构号获取机构名称
const getOrgName = (orgNo) => {
  return ORG_NAME_MAP[orgNo] || `支行${orgNo}`
}

// 支行不良数据
const branchBadLoanData = ref([])

// 行业不良数据
const industryBadLoanData = ref([])

// 业务条线不良数据
const businessLineBadLoanData = ref([])

// 账龄分析数据
const vintageAnalysisData = ref([])

// 前十大不良贷款户数据
const topBadLoanCustomers = ref([])
const isLoadingTopCustomers = ref(false)

// 支行不良贷款率动态排序图数据
const nplRaceData = ref([])
const isLoadingNPLRace = ref(false)
const isRacePlaying = ref(false)
const raceSpeed = ref(1000)  // 默认正常速度
const currentRaceMonth = ref(0)
let raceTimer = null

// 当前激活的选项卡
const activeTab = ref('branch')

// 详情弹窗相关
const showDetailDialog = ref(false)
const selectedCustomer = ref(null)

// 获取风险等级样式类
const getRiskClass = (riskLevel) => {
  const level = String(riskLevel || '').trim()
  if (level === '5' || level === '次级' || level === '可疑' || level === '损失') {
    return 'risk-high'
  } else if (level === '3' || level === '关注') {
    return 'risk-medium'
  } else if (level === '1' || level === '正常') {
    return 'risk-low'
  }
  return 'risk-unknown'
}

// 获取风险等级标签
const getRiskLabel = (riskLevel) => {
  const level = String(riskLevel || '').trim()
  const riskMap = {
    '1': '正常',
    '2': '关注',
    '3': '次级',
    '4': '可疑',
    '5': '损失',
    '0': '未分类'
  }
  return riskMap[level] || level || '未知'
}

// 计算属性：逾期60天占比
const overdue60Ratio = computed(() => {
  const latest = getLatestValue(assetData.value.overdue60Ratio)
  return latest ? latest.value : 0
})

// 计算属性：逾期90天占比
const overdue90Ratio = computed(() => {
  const latest = getLatestValue(assetData.value.overdue90Ratio)
  return latest ? latest.value : 0
})

// 逾期60天占比样式类
const overdue60RatioClass = computed(() => {
  if (overdue60Ratio.value >= 100) return 'gauge-danger'
  if (overdue60Ratio.value >= 90) return 'gauge-warning'
  return 'gauge-safe'
})

// 逾期90天占比样式类
const overdue90RatioClass = computed(() => {
  if (overdue90Ratio.value >= 100) return 'gauge-danger'
  if (overdue90Ratio.value >= 90) return 'gauge-warning'
  return 'gauge-safe'
})

// 计算属性：不良贷款率
const badLoanRate = computed(() => {
  const latest = getLatestValue(assetData.value.badLoanRate)
  return latest ? latest.value : 0
})

const badLoanRateChange = computed(() => {
  const change = getChange(assetData.value.badLoanRate)
  return change !== null ? change : 0
})

// 计算属性：不良贷款余额（数据库单位需要特殊处理）
const badLoanBalance = computed(() => {
  const latest = getLatestValue(assetData.value.badLoanBalance)
  // 数据库中的数值需要除以10000两次才能得到正确的亿元值
  // 原因：数据库中存储的可能是以"分"或其他更小单位为基准的值
  return latest ? latest.value : 0
})

const badLoanBalanceChange = computed(() => {
  const change = getChange(assetData.value.badLoanBalance)
  // 返回原始单位的变化值，在模板中统一转换
  return change !== null ? change : 0
})

// 计算属性：拨备覆盖率
const provisionCoverageRatio = computed(() => {
  const latest = getLatestValue(assetData.value.provisionCoverageRatio)
  return latest ? latest.value : 0
})

const provisionCoverageRatioChange = computed(() => {
  const change = getChange(assetData.value.provisionCoverageRatio)
  return change !== null ? change : 0
})

// 计算属性：关注类贷款占比
const attentionLoanRatio = computed(() => {
  const latest = getLatestValue(assetData.value.attentionLoanRatio)
  return latest ? latest.value : 0
})

const attentionLoanRatioChange = computed(() => {
  const change = getChange(assetData.value.attentionLoanRatio)
  return change !== null ? change : 0
})

// 计算属性：关注类贷款迁徙率（数据库中是小数，需要乘以100）
const migrationRate = computed(() => {
  const latest = getLatestValue(assetData.value.migrationRate)
  return latest ? latest.value * 100 : 0  // 转换为百分比
})

const migrationRateChange = computed(() => {
  const change = getChange(assetData.value.migrationRate)
  return change !== null ? change * 100 : 0  // 转换为百分比
})

// 计算属性：账龄分析占比（各账龄不良贷款占全部贷款的比例）
const vintageRates = computed(() => {
  if (!vintageAnalysisData.value || vintageAnalysisData.value.length === 0) {
    return {
      '1年内': 0,
      '1-2年': 0,
      '2-3年': 0,
      '3年以上': 0
    }
  }
  
  // 获取最新数据
  const latestData = vintageAnalysisData.value[vintageAnalysisData.value.length - 1]
  
  // 获取各项贷款总额（作为分母）
  const totalLoanBalance = getLatestValue(assetData.value.totalLoanBalance)
  const totalAmount = totalLoanBalance ? totalLoanBalance.value : 0
  
  if (totalAmount === 0) {
    return {
      '1年内': 0,
      '1-2年': 0,
      '2-3年': 0,
      '3年以上': 0
    }
  }
  
  // 计算各账龄不良贷款占全部贷款的比例（不良贷款余额 / 各项贷款总额）
  // 注意：数据库中的值单位是元，需要统一
  // 结果是小数形式（如0.0341），显示时会乘以100并加%符号，显示为3.41%
  return {
    '1年内': (latestData['一年内'] / totalAmount),
    '1-2年': (latestData['1-2年'] / totalAmount),
    '2-3年': (latestData['2-3年'] / totalAmount),
    '3年以上': (latestData['3年以上'] / totalAmount)
  }
})

// 图表容器引用
const trendChartRef = ref(null)
const branchTreemapRef = ref(null)
const industryTreemapRef = ref(null)
const businessLineTreemapRef = ref(null)
const attentionLoanRatioChartRef = ref(null)
const migrationRateChartRef = ref(null)
const vintageChartRef = ref(null)
const topCustomersTreemapRef = ref(null)  // 前十大不良贷款户树图
const nplRaceChartRef = ref(null)  // 不良贷款率动态排序图

// 图表实例
let trendChart = null
let branchChart = null
let industryChart = null
let businessLineChart = null
let attentionLoanRatioChart = null
let migrationRateChart = null
let vintageChart = null
let topCustomersChart = null  // 前十大不良贷款户图表实例
let nplRaceChart = null  // 不良贷款率动态排序图表实例

// 模拟数据 - 按经办机构
const branchData = [
  {
    name: '虎门支行',
    value: 285,
    rate: 2.85,
    children: [
      { name: '虎门支行-对公', value: 160, rate: 3.2 },
      { name: '虎门支行-零售', value: 125, rate: 2.5 }
    ]
  },
  {
    name: '长安支行',
    value: 212,
    rate: 2.12,
    children: [
      { name: '长安支行-对公', value: 130, rate: 2.6 },
      { name: '长安支行-零售', value: 82, rate: 1.64 }
    ]
  },
  {
    name: '东城支行',
    value: 168,
    rate: 1.68,
    children: [
      { name: '东城支行-对公', value: 95, rate: 1.9 },
      { name: '东城支行-零售', value: 73, rate: 1.46 }
    ]
  },
  {
    name: '南城支行',
    value: 105,
    rate: 1.05,
    children: [
      { name: '南城支行-对公', value: 58, rate: 1.16 },
      { name: '南城支行-零售', value: 47, rate: 0.94 }
    ]
  },
  {
    name: '松山湖支行',
    value: 95,
    rate: 0.95,
    children: [
      { name: '松山湖支行-对公', value: 52, rate: 1.04 },
      { name: '松山湖支行-零售', value: 43, rate: 0.86 }
    ]
  },
  {
    name: '其他支行',
    value: 120,
    rate: 1.20,
    children: [
      { name: '其他支行-对公', value: 68, rate: 1.36 },
      { name: '其他支行-零售', value: 52, rate: 1.04 }
    ]
  }
]

// 模拟数据 - 按贷款行业
const industryData = [
  {
    name: '制造业',
    value: 325,
    rate: 3.25,
    children: [
      { name: '电子制造', value: 145, rate: 3.6 },
      { name: '纺织服装', value: 95, rate: 3.2 },
      { name: '食品加工', value: 85, rate: 2.8 }
    ]
  },
  {
    name: '批发零售',
    value: 268,
    rate: 2.68,
    children: [
      { name: '批发业', value: 158, rate: 3.16 },
      { name: '零售业', value: 110, rate: 2.2 }
    ]
  },
  {
    name: '房地产',
    value: 192,
    rate: 1.92,
    children: [
      { name: '房地产开发', value: 115, rate: 2.3 },
      { name: '物业管理', value: 77, rate: 1.54 }
    ]
  },
  {
    name: '建筑业',
    value: 115,
    rate: 1.15,
    children: [
      { name: '房屋建筑', value: 68, rate: 1.36 },
      { name: '土木工程', value: 47, rate: 0.94 }
    ]
  },
  {
    name: '服务业',
    value: 88,
    rate: 0.88,
    children: [
      { name: '餐饮服务', value: 52, rate: 1.04 },
      { name: '其他服务', value: 36, rate: 0.72 }
    ]
  },
  {
    name: '其他',
    value: 105,
    rate: 1.05,
    children: [
      { name: '农林牧渔', value: 58, rate: 1.16 },
      { name: '其他行业', value: 47, rate: 0.94 }
    ]
  }
]

// 模拟数据 - 按贷款产品
const productData = [
  {
    name: '流动资金贷款',
    value: 295,
    rate: 2.95,
    children: [
      { name: '一般流动资金贷款', value: 175, rate: 3.5 },
      { name: '短期流动资金贷款', value: 120, rate: 2.4 }
    ]
  },
  {
    name: '固定资产贷款',
    value: 188,
    rate: 1.88,
    children: [
      { name: '基建贷款', value: 115, rate: 2.3 },
      { name: '技改贷款', value: 73, rate: 1.46 }
    ]
  },
  {
    name: '其他',
    value: 155,
    rate: 1.55,
    children: [
      { name: '并购贷款', value: 88, rate: 1.76 },
      { name: '其他贷款', value: 67, rate: 1.34 }
    ]
  },
  {
    name: '信用卡透支',
    value: 125,
    rate: 1.25,
    children: [
      { name: '个人信用卡', value: 82, rate: 1.64 },
      { name: '企业信用卡', value: 43, rate: 0.86 }
    ]
  },
  {
    name: '个人住房贷款',
    value: 65,
    rate: 0.65,
    children: [
      { name: '首套住房', value: 38, rate: 0.76 },
      { name: '二套住房', value: 27, rate: 0.54 }
    ]
  },
  {
    name: '票据贴现',
    value: 35,
    rate: 0.35,
    children: [
      { name: '银行承兑汇票', value: 22, rate: 0.44 },
      { name: '商业承兑汇票', value: 13, rate: 0.26 }
    ]
  }
]

// 初始化趋势图
const initTrendChart = () => {
  if (!trendChartRef.value) {
    console.warn('[趋势图] 图表容器未找到')
    return
  }
  
  if (!assetData.value.badLoanRate || assetData.value.badLoanRate.length === 0) {
    console.warn('[趋势图] 数据未加载或为空')
    return
  }
  
  console.log('[趋势图] 开始初始化趋势图')
  console.log('[趋势图] 不良贷款率数据:', assetData.value.badLoanRate)
  console.log('[趋势图] 不良贷款余额数据:', assetData.value.badLoanBalance)
  console.log('[趋势图] 净生成率数据:', assetData.value.netGenerationRate)
  
  // 如果图表已存在，先销毁
  if (trendChart) {
    trendChart.dispose()
  }
  
  trendChart = echarts.init(trendChartRef.value)
  
  // 准备数据 - 使用不良贷款率的日期作为基准（因为它的数据最完整）
  const dates = assetData.value.badLoanRate.map(item => {
    // 将日期格式从 YYYY-MM-DD 或 YYYYMMDD 转换为 YYYY-MM
    const dateStr = item.date.toString().replace(/-/g, '')
    return `${dateStr.substring(0, 4)}-${dateStr.substring(4, 6)}`
  })
  
  const badLoanRateData = assetData.value.badLoanRate.map(item => item.value.toFixed(2))
  const badLoanBalanceData = assetData.value.badLoanBalance.map(item => (item.value / 10000 / 10000).toFixed(2)) // 转换为亿元（数据库单位需要除以10000两次）
  
  // 拨备覆盖率数据对齐
  const provisionCoverageRatioData = dates.map((date, index) => {
    const rateDate = assetData.value.badLoanRate[index].date.toString().replace(/-/g, '')
    const found = assetData.value.provisionCoverageRatio.find(item => 
      item.date.toString().replace(/-/g, '') === rateDate
    )
    return found ? found.value.toFixed(2) : null
  })
  
  const option = {
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff'
      },
      axisPointer: {
        type: 'cross',
        crossStyle: {
          color: '#999'
        }
      }
    },
    legend: {
      data: ['不良贷款率', '不良贷款余额', '拨备覆盖率'],
      textStyle: {
        color: '#8b9dc3'
      },
      top: 10
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: dates,
      axisLine: {
        lineStyle: {
          color: '#2b5a7f'
        }
      },
      axisLabel: {
        color: '#8b9dc3',
        rotate: 45
      }
    },
    yAxis: [
      {
        type: 'value',
        name: '不良率/净生成率(%)',
        position: 'left',
        axisLine: {
          lineStyle: {
            color: '#2b5a7f'
          }
        },
        axisLabel: {
          color: '#8b9dc3',
          formatter: '{value}%'
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(43, 90, 127, 0.3)'
          }
        }
      },
      {
        type: 'value',
        name: '不良贷款余额(亿)',
        position: 'right',
        axisLine: {
          lineStyle: {
            color: '#2b5a7f'
          }
        },
        axisLabel: {
          color: '#8b9dc3',
          formatter: '{value}亿'
        },
        splitLine: {
          show: false
        }
      }
    ],
    series: [
      {
        name: '不良贷款率',
        type: 'line',
        data: badLoanRateData,
        smooth: true,
        yAxisIndex: 0,
        itemStyle: {
          color: '#ff4d4f'
        },
        lineStyle: {
          width: 2
        }
      },
      {
        name: '不良贷款余额',
        type: 'line',
        data: badLoanBalanceData,
        smooth: true,
        yAxisIndex: 1,
        itemStyle: {
          color: '#faad14'
        },
        lineStyle: {
          width: 2
        }
      },
      {
        name: '拨备覆盖率',
        type: 'line',
        data: provisionCoverageRatioData,
        smooth: true,
        yAxisIndex: 0,
        itemStyle: {
          color: '#52c41a'
        },
        lineStyle: {
          width: 2
        }
      }
    ]
  }
  
  trendChart.setOption(option)
  
  console.log('[趋势图] 趋势图初始化完成')
  console.log('[趋势图] 日期范围:', dates[0], '~', dates[dates.length - 1])
  console.log('[趋势图] 数据点数:', dates.length)
  
  // 监听窗口大小变化
  window.addEventListener('resize', () => {
    if (trendChart) {
      trendChart.resize()
    }
  })
}

// 初始化关注类贷款占比折线图
const initAttentionLoanRatioChart = () => {
  if (!attentionLoanRatioChartRef.value) {
    console.warn('[关注类贷款占比图表] 图表容器未找到')
    return
  }
  
  if (!assetData.value.attentionLoanRatio || assetData.value.attentionLoanRatio.length === 0) {
    console.warn('[关注类贷款占比图表] 没有数据')
    return
  }
  
  console.log('[关注类贷款占比图表] 开始初始化')
  
  // 如果图表已存在，先销毁
  if (attentionLoanRatioChart) {
    attentionLoanRatioChart.dispose()
  }
  
  attentionLoanRatioChart = echarts.init(attentionLoanRatioChartRef.value)
  
  // 准备数据
  const dates = assetData.value.attentionLoanRatio.map(item => {
    const dateStr = item.date.toString().replace(/-/g, '')
    return `${dateStr.substring(0, 4)}-${dateStr.substring(4, 6)}`
  })
  
  const values = assetData.value.attentionLoanRatio.map(item => item.value.toFixed(2))
  
  const option = {
    grid: {
      left: '5%',
      right: '5%',
      top: '15%',
      bottom: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: dates,
      axisLine: {
        lineStyle: {
          color: 'rgba(139, 157, 195, 0.3)'
        }
      },
      axisLabel: {
        color: '#8b9dc3',
        fontSize: 10,
        interval: Math.floor(dates.length / 6) // 只显示部分标签
      },
      axisTick: {
        show: false
      }
    },
    yAxis: {
      type: 'value',
      axisLine: {
        show: false
      },
      axisLabel: {
        color: '#8b9dc3',
        fontSize: 10,
        formatter: '{value}%'
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(139, 157, 195, 0.1)'
        }
      }
    },
    series: [
      {
        data: values,
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 4,
        lineStyle: {
          color: '#faad14',
          width: 2
        },
        itemStyle: {
          color: '#faad14'
        },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: 'rgba(250, 173, 20, 0.3)'
              },
              {
                offset: 1,
                color: 'rgba(250, 173, 20, 0.05)'
              }
            ]
          }
        }
      }
    ],
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff'
      },
      formatter: (params) => {
        const param = params[0]
        return `${param.name}<br/>关注类占比: <span style="color: #faad14; font-weight: bold;">${param.value}%</span>`
      }
    }
  }
  
  attentionLoanRatioChart.setOption(option)
  
  console.log('[关注类贷款占比图表] 图表初始化完成')
  
  // 监听窗口大小变化
  window.addEventListener('resize', () => {
    if (attentionLoanRatioChart) {
      attentionLoanRatioChart.resize()
    }
  })
}

// 初始化关注类贷款迁徙率折线图
const initMigrationRateChart = () => {
  if (!migrationRateChartRef.value) {
    console.warn('[关注类贷款迁徙率图表] 图表容器未找到')
    return
  }
  
  if (!assetData.value.migrationRate || assetData.value.migrationRate.length === 0) {
    console.warn('[关注类贷款迁徙率图表] 没有数据')
    return
  }
  
  console.log('[关注类贷款迁徙率图表] 开始初始化')
  
  // 如果图表已存在，先销毁
  if (migrationRateChart) {
    migrationRateChart.dispose()
  }
  
  migrationRateChart = echarts.init(migrationRateChartRef.value)
  
  // 准备数据（数据库中是小数，需要乘以100转为百分比）
  const dates = assetData.value.migrationRate.map(item => {
    const dateStr = item.date.toString().replace(/-/g, '')
    return `${dateStr.substring(0, 4)}-${dateStr.substring(4, 6)}`
  })
  
  const values = assetData.value.migrationRate.map(item => (item.value * 100).toFixed(2))
  
  const option = {
    grid: {
      left: '5%',
      right: '5%',
      top: '15%',
      bottom: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: dates,
      axisLine: {
        lineStyle: {
          color: 'rgba(139, 157, 195, 0.3)'
        }
      },
      axisLabel: {
        color: '#8b9dc3',
        fontSize: 10,
        interval: Math.floor(dates.length / 6)
      },
      axisTick: {
        show: false
      }
    },
    yAxis: {
      type: 'value',
      axisLine: {
        show: false
      },
      axisLabel: {
        color: '#8b9dc3',
        fontSize: 10,
        formatter: '{value}%'
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(139, 157, 195, 0.1)'
        }
      }
    },
    series: [
      {
        data: values,
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 4,
        lineStyle: {
          color: '#ff4d4f',
          width: 2
        },
        itemStyle: {
          color: '#ff4d4f'
        },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              {
                offset: 0,
                color: 'rgba(255, 77, 79, 0.3)'
              },
              {
                offset: 1,
                color: 'rgba(255, 77, 79, 0.05)'
              }
            ]
          }
        }
      }
    ],
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff'
      },
      formatter: (params) => {
        const param = params[0]
        return `${param.name}<br/>迁徙率: <span style="color: #ff4d4f; font-weight: bold;">${param.value}%</span>`
      }
    }
  }
  
  migrationRateChart.setOption(option)
  
  console.log('[关注类贷款迁徙率图表] 图表初始化完成')
  
  // 监听窗口大小变化
  window.addEventListener('resize', () => {
    if (migrationRateChart) {
      migrationRateChart.resize()
    }
  })
}

// 初始化账龄分析柱状图
const initVintageChart = () => {
  if (!vintageChartRef.value) {
    console.warn('[账龄分析图表] 图表容器未找到')
    return
  }
  
  if (!vintageRates.value) {
    console.warn('[账龄分析图表] 没有数据')
    return
  }
  
  console.log('[账龄分析图表] 开始初始化')
  console.log('[账龄分析图表] 账龄不良率数据:', vintageRates.value)
  
  // 如果图表已存在，先销毁
  if (vintageChart) {
    vintageChart.dispose()
  }
  
  vintageChart = echarts.init(vintageChartRef.value)
  
  const categories = ['1年内', '1-2年', '2-3年', '3年以上']
  const values = [
    vintageRates.value['1年内'],
    vintageRates.value['1-2年'],
    vintageRates.value['2-3年'],
    vintageRates.value['3年以上']
  ]
  
  // 根据占比设置颜色（按相对大小排序，从小到大：蓝->绿->橙->红）
  const sortedValues = [...values].sort((a, b) => a - b)
  const colors = values.map(rate => {
    const rank = sortedValues.indexOf(rate)
    if (rank === 3) return '#ff4d4f'      // 红色 - 最高
    if (rank === 2) return '#faad14'      // 橙色 - 较高
    if (rank === 1) return '#52c41a'      // 绿色 - 较低
    return '#1890ff'                      // 蓝色 - 最低
  })
  
  const option = {
    title: {
      text: '按账龄分析的不良贷款率',
      subtext: '各账龄不良贷款余额占全部贷款的比例',
      left: 'center',
      top: 20,
      textStyle: {
        color: '#00d7e9',
        fontSize: 18,
        fontWeight: 500
      },
      subtextStyle: {
        color: '#8b9dc3',
        fontSize: 12
      }
    },
    grid: {
      left: '10%',
      right: '10%',
      top: '28%',
      bottom: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: categories,
      axisLine: {
        lineStyle: {
          color: 'rgba(139, 157, 195, 0.3)'
        }
      },
      axisLabel: {
        color: '#8b9dc3',
        fontSize: 14
      },
      axisTick: {
        show: false
      }
    },
    yAxis: {
      type: 'value',
      name: '占比 (%)',
      nameTextStyle: {
        color: '#8b9dc3',
        fontSize: 12
      },
      axisLine: {
        show: false
      },
      axisLabel: {
        color: '#8b9dc3',
        fontSize: 12,
        formatter: (value) => {
          return (value * 100).toFixed(1) + '%'
        }
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(139, 157, 195, 0.1)'
        }
      }
    },
    series: [
      {
        type: 'bar',
        data: values.map((value, index) => ({
          value: value,
          itemStyle: {
            color: colors[index],
            borderRadius: [4, 4, 0, 0]
          }
        })),
        barWidth: '40%',
        label: {
          show: true,
          position: 'top',
          formatter: (params) => {
            return (params.value * 100).toFixed(2) + '%'
          },
          color: '#fff',
          fontSize: 14,
          fontWeight: 'bold'
        }
      }
    ],
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff'
      },
      formatter: (params) => {
        const param = params[0]
        return `${param.name}<br/>占比: <span style="color: ${colors[param.dataIndex]}; font-weight: bold;">${(param.value * 100).toFixed(2)}%</span>`
      }
    }
  }
  
  vintageChart.setOption(option)
  
  console.log('[账龄分析图表] 图表初始化完成')
  
  // 监听窗口大小变化
  window.addEventListener('resize', () => {
    if (vintageChart) {
      vintageChart.resize()
    }
  })
}

// 根据不良率获取颜色
const getRateColor = (rate) => {
  if (rate >= 2.5) {
    return '#ff4d4f' // 红色 - 高风险
  } else if (rate >= 1.5) {
    return '#faad14' // 橙色 - 中风险
  } else {
    return '#52c41a' // 绿色 - 低风险
  }
}

// 初始化树图
const initTreemap = (chartRef, data, title) => {
  if (!chartRef) return null
  
  const chart = echarts.init(chartRef)
  
  const option = {
    title: {
      text: title,
      left: 'center',
      top: 10,
      textStyle: {
        color: '#fff',
        fontSize: 16,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      formatter: (info) => {
        const { name, value, data } = info
        
        // 格式化数值显示
        const valueInYi = (value / 10000).toFixed(2) // 转换为亿元
        const valueFormatted = value.toLocaleString('zh-CN', { maximumFractionDigits: 2 }) // 万元，带千分位
        
        const lines = [
          `<div style="font-weight: bold; margin-bottom: 5px;">${name}</div>`,
          `不良贷款额: <span style="color: #ff4d4f; font-weight: bold;">${valueInYi}</span> 亿元`,
          `　　　　　: <span style="color: #ff4d4f;">${valueFormatted}</span> 万元`
        ]
        
        // 不显示不良率（因为没有各行业贷款总额数据）
        // 如果未来有数据，可以取消下面的注释
        // const rate = data.rate || 0
        // if (rate > 0) {
        //   lines.push(`不良率: <span style="color: ${getRateColor(rate)}; font-weight: bold;">${rate.toFixed(2)}%</span>`)
        // }
        
        return lines.join('<br/>')
      },
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff'
      }
    },
    series: [
      {
        type: 'treemap',
        width: '100%',
        height: '85%',
        top: '12%',
        roam: false,
        nodeClick: false,
        breadcrumb: {
          show: false
        },
        label: {
          show: true,
          formatter: (params) => {
            const { name, value } = params
            // 只显示行业名称和不良贷款额（亿元）
            const valueInYi = (value / 10000).toFixed(2)
            return `${name}\n${valueInYi}亿`
          },
          fontSize: 14,
          color: '#fff',
          fontWeight: 'bold'
        },
        upperLabel: {
          show: true,
          height: 30,
          color: '#fff',
          backgroundColor: 'rgba(0, 0, 0, 0.5)'
        },
        itemStyle: {
          borderColor: '#033c76',
          borderWidth: 3,
          gapWidth: 3
        },
        levels: [
          {
            itemStyle: {
              borderWidth: 3,
              gapWidth: 3
            }
          },
          {
            colorSaturation: [0.3, 0.6],
            itemStyle: {
              gapWidth: 1,
              borderColorSaturation: 0.6
            }
          }
        ],
        data: data.map((item, index) => {
          // 根据不良贷款额排名设置颜色（从红到绿的渐变）
          const totalItems = data.length
          const ratio = index / totalItems
          
          let color
          if (ratio < 0.2) {
            color = '#ff4d4f' // 前20% - 红色（风险最高）
          } else if (ratio < 0.4) {
            color = '#ff7a45' // 20-40% - 橙红色
          } else if (ratio < 0.6) {
            color = '#ffa940' // 40-60% - 橙色
          } else if (ratio < 0.8) {
            color = '#95de64' // 60-80% - 黄绿色
          } else {
            color = '#52c41a' // 后20% - 绿色（风险最低）
          }
          
          return {
            ...item,
            itemStyle: {
              color: color
            },
            children: item.children?.map(child => ({
              ...child,
              itemStyle: {
                color: color
              }
            }))
          }
        })
      }
    ]
  }
  
  chart.setOption(option)
  
  // 监听窗口大小变化
  window.addEventListener('resize', () => {
    chart.resize()
  })
  
  return chart
}

// 初始化前十大不良贷款户树图
const initTopCustomersTreemap = () => {
  if (!topCustomersTreemapRef.value) {
    console.warn('[前十大不良贷款户] 图表容器未找到')
    return
  }
  
  if (!topBadLoanCustomers.value || topBadLoanCustomers.value.length === 0) {
    console.warn('[前十大不良贷款户] 没有数据')
    return
  }
  
  console.log('[前十大不良贷款户] 开始初始化树图')
  
  // 如果图表已存在，先销毁
  if (topCustomersChart) {
    topCustomersChart.dispose()
  }
  
  topCustomersChart = echarts.init(topCustomersTreemapRef.value)
  
  // 准备数据 - 数据库中单位是元，需要转换为万元
  const formattedData = topBadLoanCustomers.value.map((customer, index) => {
    const valueInWan = customer.value / 10000  // 转换为万元
    
    // 根据排名设置颜色
    let color
    if (index < 3) {
      color = '#ff4d4f' // 前3名 - 红色（最高风险）
    } else if (index < 6) {
      color = '#ff7a45' // 4-6名 - 橙红色
    } else if (index < 8) {
      color = '#ffa940' // 7-8名 - 橙色
    } else {
      color = '#faad14' // 9-10名 - 黄色
    }
    
    return {
      name: customer.name,
      value: valueInWan,
      itemStyle: {
        color: color
      },
      // 保存原始数据用于点击事件
      customerData: customer
    }
  })
  
  const option = {
    title: {
      text: '📊 前十大不良贷款户分布',
      left: 'center',
      top: 10,
      textStyle: {
        color: '#00d7e9',
        fontSize: 16,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      formatter: (info) => {
        const { name, value, data } = info
        const customer = data.customerData
        
        // 格式化数值显示
        const valueInYi = (value / 10000).toFixed(2) // 亿元
        const valueFormatted = value.toLocaleString('zh-CN', { maximumFractionDigits: 2 }) // 万元，带千分位
        
        const lines = [
          `<div style="font-weight: bold; margin-bottom: 8px; font-size: 14px;">${name}</div>`,
          `<div style="margin-bottom: 5px;">不良贷款总额: <span style="color: #ff4d4f; font-weight: bold;">${valueInYi}</span> 亿元</div>`,
          `<div style="margin-bottom: 5px; padding-left: 20px;"><span style="color: #ff4d4f;">${valueFormatted}</span> 万元</div>`,
          `<div style="margin-top: 5px; color: #8b9dc3;">借据数量: ${customer.loanCount} 笔</div>`,
          `<div style="margin-top: 8px; font-size: 12px; color: #52c41a;">💡 点击查看详情</div>`
        ]
        
        return lines.join('')
      },
      backgroundColor: 'rgba(0, 0, 0, 0.9)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff'
      },
      padding: 12
    },
    series: [
      {
        type: 'treemap',
        width: '100%',
        height: '88%',
        top: '10%',
        roam: false,
        nodeClick: 'link',  // 启用点击
        breadcrumb: {
          show: false
        },
        label: {
          show: true,
          formatter: (params) => {
            const { name, value } = params
            const valueInYi = (value / 10000).toFixed(2)
            return `${name}\n${valueInYi}亿元`
          },
          fontSize: 13,
          color: '#fff',
          fontWeight: 'bold',
          overflow: 'truncate',
          ellipsis: '...'
        },
        upperLabel: {
          show: false
        },
        itemStyle: {
          borderColor: '#033c76',
          borderWidth: 2,
          gapWidth: 2
        },
        emphasis: {
          itemStyle: {
            borderColor: '#00d7e9',
            borderWidth: 3,
            shadowBlur: 10,
            shadowColor: 'rgba(0, 215, 233, 0.5)'
          }
        },
        data: formattedData
      }
    ]
  }
  
  topCustomersChart.setOption(option)
  
  // 添加点击事件
  topCustomersChart.on('click', (params) => {
    if (params.data && params.data.customerData) {
      console.log('[前十大不良贷款户] 点击客户:', params.data.customerData)
      selectedCustomer.value = params.data.customerData
      showDetailDialog.value = true
    }
  })
  
  // 监听窗口大小变化
  window.addEventListener('resize', () => {
    if (topCustomersChart) {
      topCustomersChart.resize()
    }
  })
  
  console.log('[前十大不良贷款户] 树图初始化完成')
}

// 初始化支行不良贷款率动态排序图
const initNPLRaceChart = () => {
  if (!nplRaceChartRef.value || nplRaceData.value.length === 0) {
    console.warn('[NPL动态排行] 图表容器未找到或无数据')
    return
  }
  
  console.log('[NPL动态排行] 开始初始化，数据条数:', nplRaceData.value.length)
  console.log('[NPL动态排行] 第一条数据结构:', nplRaceData.value[0])
  
  if (nplRaceChart) {
    nplRaceChart.dispose()
  }
  
  nplRaceChart = echarts.init(nplRaceChartRef.value)
  
  // 数据处理：按月份分组
  const dataByMonth = {}
  const branches = new Set()
  
  nplRaceData.value.forEach((row, idx) => {
    if (idx < 3) {
      console.log(`[NPL动态排行] 第${idx}条数据:`, row)
    }
    
    // 字段映射：select buss_dt, index_nm, org_no, index_value, ori from audit_index_total
    const month = row[0]  // buss_dt: 业务日期，格式：2025-09-30
    const orgNo = row[2]  // org_no: 机构号
    const nplRate = parseFloat(row[3]) || 0  // index_value: 不良贷款率值
    
    // 根据机构号获取机构名称
    const orgName = getOrgName(orgNo)
    
    if (idx < 3) {
      console.log(`[NPL动态排行] 解析结果: month=${month}, orgNo=${orgNo}, orgName=${orgName}, nplRate=${nplRate}`)
    }
    
    branches.add(orgName)
    
    if (!dataByMonth[month]) {
      dataByMonth[month] = []
    }
    
    dataByMonth[month].push({
      name: orgName,
      value: nplRate,
      orgNo: orgNo
    })
  })
  
  const months = Object.keys(dataByMonth).sort()
  const recentMonths = months.slice(-12)  // 只取最近12个月
  
  console.log('[NPL动态排行] 所有月份:', months)
  console.log('[NPL动态排行] 最近12个月:', recentMonths)
  console.log('[NPL动态排行] 支行数量:', branches.size)
  
  if (recentMonths.length === 0) {
    console.warn('[NPL动态排行] 没有有效月份数据')
    return
  }
  
  const startMonth = recentMonths[0]
  const startData = dataByMonth[startMonth].sort((a, b) => b.value - a.value).slice(0, 10)
  
  console.log('[NPL动态排行] 起始月份:', startMonth)
  console.log('[NPL动态排行] 起始数据:', startData)
  
  const option = {
    grid: {
      top: 80,
      bottom: 80,
      left: 180,
      right: 150
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      },
      backgroundColor: 'rgba(0, 0, 0, 0.9)',
      borderColor: '#00d7e9',
      borderWidth: 1,
      textStyle: {
        color: '#fff',
        fontSize: 13
      },
      formatter: (params) => {
        const data = params[0]
        const item = startData[data.dataIndex]
        return `
          <div style="padding: 5px;">
            <div style="font-weight: bold; color: #00d7e9; margin-bottom: 5px;">${item.name}</div>
            <div>不良贷款率: <span style="color: #ff4d4f; font-weight: bold; font-family: monospace;">${item.value.toFixed(2)}%</span></div>
            <div style="margin-top: 3px; color: #8b9dc3; font-size: 11px;">排名: 第 ${data.dataIndex + 1} 位</div>
          </div>
        `
      }
    },
    xAxis: {
      max: 'dataMax',
      axisLabel: {
        formatter: (n) => n.toFixed(2) + '%',
        color: '#8b9dc3'
      },
      axisLine: {
        lineStyle: { color: 'rgba(0, 215, 233, 0.3)' }
      },
      splitLine: {
        lineStyle: { color: 'rgba(0, 215, 233, 0.1)' }
      }
    },
    yAxis: {
      type: 'category',
      data: startData.map(item => item.name),
      inverse: true,
      axisLabel: {
        show: true,
        fontSize: 14,
        color: '#00d7e9',
        fontWeight: 'bold'
      },
      axisLine: { show: false },
      axisTick: { show: false },
      animationDuration: 300,
      animationDurationUpdate: 300
    },
    series: [{
      realtimeSort: true,
      type: 'bar',
      data: startData.map(item => item.value),
      itemStyle: {
        color: (param) => {
          const colors = ['#ff4d4f', '#ff7875', '#ffa940', '#ffc069', '#faad14', 
                          '#ffd666', '#52c41a', '#73d13d', '#1890ff', '#40a9ff']
          return colors[param.dataIndex % colors.length]
        }
      },
      label: {
        show: true,
        precision: 2,
        position: 'right',
        valueAnimation: true,
        formatter: (params) => {
          return `  ${params.value.toFixed(2)}%`
        },
        color: '#fff',
        fontSize: 14,
        fontWeight: 'bold',
        fontFamily: 'monospace'
      },
      barWidth: 30
    }],
    animationDuration: 0,
    animationDurationUpdate: raceSpeed.value,
    animationEasing: 'linear',
    animationEasingUpdate: 'linear',
    graphic: {
      elements: [{
        type: 'text',
        right: 60,
        bottom: 20,
        style: {
          text: startMonth,
          font: 'bolder 120px monospace',
          fill: 'rgba(0, 215, 233, 0.3)'
        },
        z: 100
      }]
    }
  }
  
  nplRaceChart.setOption(option)
  
  // 存储月份数据以便播放
  nplRaceChart._raceMonths = recentMonths
  nplRaceChart._raceDataByMonth = dataByMonth
  
  console.log('[NPL动态排行] 图表初始化完成，共', recentMonths.length, '个月')
}

// 播放/暂停动画
const toggleRaceAnimation = () => {
  if (!nplRaceChart) return
  
  if (isRacePlaying.value) {
    // 暂停
    clearTimeout(raceTimer)
    isRacePlaying.value = false
  } else {
    // 播放
    isRacePlaying.value = true
    playRaceAnimation()
  }
}

// 播放动画
const playRaceAnimation = () => {
  if (!nplRaceChart || !nplRaceChart._raceMonths) return
  
  const months = nplRaceChart._raceMonths
  const dataByMonth = nplRaceChart._raceDataByMonth
  
  if (currentRaceMonth.value >= months.length - 1) {
    currentRaceMonth.value = 0
  }
  
  const updateMonth = () => {
    if (!isRacePlaying.value) return
    
    currentRaceMonth.value++
    
    if (currentRaceMonth.value >= months.length) {
      isRacePlaying.value = false
      currentRaceMonth.value = months.length - 1
      return
    }
    
    const month = months[currentRaceMonth.value]
    const monthData = dataByMonth[month].sort((a, b) => b.value - a.value).slice(0, 10)
    
    nplRaceChart.setOption({
      yAxis: {
        data: monthData.map(item => item.name)
      },
      series: [{
        data: monthData.map(item => item.value)
      }],
      graphic: {
        elements: [{
          type: 'text',
          right: 60,
          bottom: 20,
          style: {
            text: month,
            font: 'bolder 120px monospace',
            fill: 'rgba(0, 215, 233, 0.3)'
          },
          z: 100
        }]
      }
    })
    
    raceTimer = setTimeout(updateMonth, raceSpeed.value)
  }
  
  raceTimer = setTimeout(updateMonth, raceSpeed.value)
}

// 重置动画
const resetRaceAnimation = () => {
  if (!nplRaceChart || !nplRaceChart._raceMonths) return
  
  clearTimeout(raceTimer)
  isRacePlaying.value = false
  currentRaceMonth.value = 0
  
  const months = nplRaceChart._raceMonths
  const dataByMonth = nplRaceChart._raceDataByMonth
  const startMonth = months[0]
  const startData = dataByMonth[startMonth].sort((a, b) => b.value - a.value).slice(0, 10)
  
  nplRaceChart.setOption({
    series: [{ data: startData }],
    graphic: {
      elements: [{
        style: { text: startMonth }
      }]
    }
  })
}

// 更新播放速度
const updateRaceSpeed = () => {
  if (nplRaceChart) {
    nplRaceChart.setOption({
      animationDurationUpdate: parseInt(raceSpeed.value)
    })
  }
}

// 组件挂载后初始化图表和获取数据
onMounted(async () => {
  console.log('[资产质量页面] 组件已挂载')
  
  // 检查 Store 中是否已有数据
  if (assetQualityStore.hasData.value) {
    console.log('[资产质量页面] 从 Store 读取缓存数据')
    console.log('[资产质量页面] 最后更新时间:', assetQualityStore.lastUpdateTime.value ? new Date(assetQualityStore.lastUpdateTime.value).toLocaleString() : '未知')
    
    // ⚠️ 重要：恢复核心数据到 useAssetQuality 的 assetData（触发计算属性更新）
    const cachedAssetData = assetQualityStore.getAssetData()
    if (cachedAssetData && Object.keys(cachedAssetData).length > 0) {
      console.log('[资产质量页面] 恢复核心资产数据')
      setAssetData(cachedAssetData)  // 使用新增的 setAssetData 方法恢复数据
    }
    
    // 从 Store 读取其他数据
    branchBadLoanData.value = assetQualityStore.getBranchData()
    industryBadLoanData.value = assetQualityStore.getIndustryData()
    businessLineBadLoanData.value = assetQualityStore.getBusinessLineData()
    topBadLoanCustomers.value = assetQualityStore.getTopBadLoanCustomers()
    
    console.log('[资产质量页面] 从缓存加载：支行数据', branchBadLoanData.value.length, '条')
    console.log('[资产质量页面] 从缓存加载：行业数据', industryBadLoanData.value.length, '条')
    console.log('[资产质量页面] 从缓存加载：业务条线数据', businessLineBadLoanData.value.length, '条')
    console.log('[资产质量页面] 从缓存加载：前十大不良贷款户', topBadLoanCustomers.value.length, '户')
    
    // 初始化图表（使用缓存数据）
    nextTick(() => {
      initTrendChart()
      initAttentionLoanRatioChart()
      initMigrationRateChart()
      
      // 初始化默认显示的树图（按经办机构）
      if (branchBadLoanData.value && branchBadLoanData.value.length > 0) {
        const formattedBranchData = branchBadLoanData.value.map(item => ({
          name: item.name,
          value: item.value / 10000, // 转换为万元
          rate: item.rate || 0
        }))
        branchChart = initTreemap(branchTreemapRef.value, formattedBranchData, '📊 矩形树图 - 按经办机构')
      }
      
      // 初始化前十大不良贷款户树图（如果有缓存数据）
      if (topBadLoanCustomers.value && topBadLoanCustomers.value.length > 0) {
        console.log('[资产质量页面] 使用缓存数据初始化前十大不良贷款户树图')
        initTopCustomersTreemap()
      }
    })
    
    return // 有缓存数据，直接返回，不再重复请求
  }
  
  // Store 中没有数据，开始获取资产质量数据
  console.log('[资产质量页面] Store 中无缓存，开始获取数据...')
  
  try {
    assetQualityStore.setLoading(true)
    
    // 并行加载核心指标数据、支行数据、行业不良数据和业务条线数据
    const [coreData, branchData, industryData, businessLineData] = await Promise.all([
      fetchAssetQualityData('00000'),
      fetchBranchBadLoanData(),
      fetchIndustryBadLoanData('00000'),
      fetchBusinessLineBadLoanData('00000')
      // fetchVintageAnalysisData()  // 已隐藏账龄分析模块
    ])
    
    // 异步加载前十大不良贷款户数据（不阻塞主流程）
    isLoadingTopCustomers.value = true
    fetchTopBadLoanCustomers('20250930').then(customersData => {
      topBadLoanCustomers.value = customersData
      console.log('[资产质量页面] 前十大不良贷款户数据加载成功，共', customersData.length, '户')
      
      // 保存到 Store
      assetQualityStore.setTopBadLoanCustomers(customersData)
      
      // 等待DOM更新后再初始化树图
      nextTick(() => {
        isLoadingTopCustomers.value = false
        // 再等一个tick确保loading状态已经更新，容器已经渲染
        nextTick(() => {
          initTopCustomersTreemap()
        })
      })
    }).catch(err => {
      console.error('[资产质量页面] 前十大不良贷款户数据加载失败:', err)
      isLoadingTopCustomers.value = false
    })
    
    // 异步加载支行不良贷款率动态排序数据（不阻塞主流程）
    isLoadingNPLRace.value = true
    fetchBranchNPLRateTimeSeries().then(raceData => {
      nplRaceData.value = raceData
      console.log('[资产质量页面] NPL动态排行数据加载成功，共', raceData.length, '条')
      
      nextTick(() => {
        isLoadingNPLRace.value = false
        nextTick(() => {
          initNPLRaceChart()
        })
      })
    }).catch(err => {
      console.error('[资产质量页面] NPL动态排行数据加载失败:', err)
      isLoadingNPLRace.value = false
    })
    
    // 保存到本地变量
    branchBadLoanData.value = branchData
    industryBadLoanData.value = industryData
    businessLineBadLoanData.value = businessLineData
    // vintageAnalysisData.value = vintageData  // 已隐藏账龄分析模块
    
    // 保存到 Store（供下次使用）
    assetQualityStore.setAssetData(coreData)
    assetQualityStore.setBranchData(branchData)
    assetQualityStore.setIndustryData(industryData)
    assetQualityStore.setBusinessLineData(businessLineData)
    
    console.log('[资产质量页面] 数据加载成功并已保存到 Store')
    console.log('[资产质量页面] 支行数据:', branchData.length, '条')
    console.log('[资产质量页面] 行业不良数据:', industryData.length, '条')
    console.log('[资产质量页面] 业务条线数据:', businessLineData.length, '条')
    // console.log('[资产质量页面] 账龄分析数据:', vintageData)  // 已隐藏账龄分析模块
    
    // 数据加载成功后，初始化图表
    nextTick(() => {
      initTrendChart()
      initAttentionLoanRatioChart()
      initMigrationRateChart()
      // initVintageChart()  // 已隐藏账龄分析模块
      
      // 只初始化默认显示的图表（按经办机构）
      if (branchBadLoanData.value && branchBadLoanData.value.length > 0) {
        console.log('[资产质量页面] 使用真实支行数据初始化树图')
        const formattedBranchData = branchBadLoanData.value.map(item => {
          // 数据库单位是元，需要转换为万元
          const valueInWan = item.value / 10000
          
          return {
            name: item.name,
            value: valueInWan, // 万元
            rate: item.rate || 0
          }
        })
        console.log('[资产质量页面] 格式化后的支行数据:', formattedBranchData.slice(0, 3))
        branchChart = initTreemap(branchTreemapRef.value, formattedBranchData, '📊 矩形树图 - 按经办机构')
      } else {
        console.warn('[资产质量页面] 没有真实支行数据，使用模拟数据')
        branchChart = initTreemap(branchTreemapRef.value, branchData, '📊 矩形树图 - 按经办机构')
      }
      
      // 行业树图在切换标签时初始化（通过watch监听）
      console.log('[资产质量页面] 行业数据已准备就绪，等待标签切换时初始化')
    })
  } catch (err) {
    console.error('[资产质量页面] 数据加载失败:', err)
  } finally {
    assetQualityStore.setLoading(false)
  }
})

// 监听数据变化，重新绘制趋势图
watch(() => assetData.value, (newData) => {
  if (newData && newData.badLoanRate && newData.badLoanRate.length > 0) {
    nextTick(() => {
      initTrendChart()
    })
  }
}, { deep: true })

// 监听tab切换，初始化对应的图表
watch(activeTab, (newTab) => {
  console.log('[资产质量页面] 切换到标签:', newTab)
  
  nextTick(() => {
    if (newTab === 'branch') {
      if (!branchChart) {
        console.log('[资产质量页面] 初始化按经办机构树图')
        if (branchBadLoanData.value && branchBadLoanData.value.length > 0) {
          const formattedBranchData = branchBadLoanData.value.map(item => {
            const valueInWan = item.value / 10000
            return {
              name: item.name,
              value: valueInWan,
              rate: item.rate || 0
            }
          })
          branchChart = initTreemap(branchTreemapRef.value, formattedBranchData, '📊 矩形树图 - 按经办机构')
        } else {
          branchChart = initTreemap(branchTreemapRef.value, branchData, '📊 矩形树图 - 按经办机构')
        }
      } else {
        console.log('[资产质量页面] 支行树图已存在，调整大小')
        branchChart.resize()
      }
    } else if (newTab === 'industry') {
      console.log('[资产质量页面] 准备初始化按贷款行业树图')
      console.log('[资产质量页面] industryChart存在:', !!industryChart)
      console.log('[资产质量页面] industryBadLoanData长度:', industryBadLoanData.value?.length)
      
      if (!industryChart) {
        // 使用真实的行业数据
        if (industryBadLoanData.value && industryBadLoanData.value.length > 0) {
          console.log('[资产质量页面] 使用真实行业数据初始化树图')
          const formattedIndustryData = industryBadLoanData.value.map(item => {
            // 数据库单位是元，需要转换为万元
            const valueInWan = item.value / 10000
            
            return {
              name: item.name,
              value: valueInWan, // 万元
              rate: item.rate || 0 // 使用数据库中的不良率，如果没有则为0
            }
          })
          console.log('[资产质量页面] 格式化后的数据:', formattedIndustryData.slice(0, 3))
          industryChart = initTreemap(industryTreemapRef.value, formattedIndustryData, '📊 矩形树图 - 按贷款行业')
        } else {
          console.warn('[资产质量页面] 没有真实数据，使用模拟数据')
          industryChart = initTreemap(industryTreemapRef.value, industryData, '📊 矩形树图 - 按贷款行业')
        }
      } else {
        console.log('[资产质量页面] 行业树图已存在，调整大小')
        industryChart.resize()
      }
    } else if (newTab === 'businessLine') {
      console.log('[资产质量页面] 准备初始化按业务条线树图')
      console.log('[资产质量页面] businessLineChart存在:', !!businessLineChart)
      console.log('[资产质量页面] businessLineBadLoanData长度:', businessLineBadLoanData.value?.length)
      
      if (!businessLineChart) {
        // 使用真实的业务条线数据
        if (businessLineBadLoanData.value && businessLineBadLoanData.value.length > 0) {
          console.log('[资产质量页面] 使用真实业务条线数据初始化树图')
          const formattedBusinessLineData = businessLineBadLoanData.value.map(item => {
            // 数据库单位是元，需要转换为万元
            const valueInWan = item.value / 10000
            
            return {
              name: item.name,
              value: valueInWan, // 万元
              rate: item.rate || 0
            }
          })
          console.log('[资产质量页面] 格式化后的数据:', formattedBusinessLineData)
          businessLineChart = initTreemap(businessLineTreemapRef.value, formattedBusinessLineData, '📊 矩形树图 - 按业务条线')
        } else {
          console.warn('[资产质量页面] 没有真实业务条线数据')
        }
      } else {
        console.log('[资产质量页面] 业务条线树图已存在，调整大小')
        businessLineChart.resize()
      }
    }
  })
})
</script>

<style scoped>
.asset-quality-audit-view {
  width: 100%;
  min-height: 100vh;
  background: #033c76;
  padding: 0;
}

/* 内容包装器 */
.content-wrapper {
  padding: 15px;
}

/* 通用 section 样式 */
.section {
  margin-bottom: 15px;
}

.box {
  border: 1px solid rgba(7, 118, 181, 0.5);
  box-shadow: inset 0 0 10px rgba(7, 118, 181, 0.4);
  background: rgba(6, 30, 93, 0.5);
  padding: 20px;
  border-radius: 4px;
}

.tit {
  color: #00d7e9;
  font-size: 18px;
  font-weight: 500;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(0, 215, 233, 0.2);
}

/* 第一行：核心仪表盘 */
.dashboard-row {
  display: flex;
  gap: 15px;
}

.kri-card {
  background: rgba(6, 30, 93, 0.5);
  border: 1px solid rgba(0, 215, 233, 0.3);
  border-radius: 4px;
  padding: 20px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.kri-card-large {
  flex: 0 0 60%;
}

.kri-card-medium {
  flex: 0 0 calc(40% - 15px);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.card-header h3 {
  color: #00d7e9;
  font-size: 20px;
  margin: 0;
}

.time-label {
  color: #8b9dc3;
  font-size: 12px;
}

.indicators-group {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.indicator-mini {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.indicator-mini .label {
  color: #8b9dc3;
  font-size: 12px;
}

.indicator-mini .value {
  color: #fff;
  font-size: 24px;
  font-weight: bold;
}

.indicator-mini .value .unit {
  font-size: 14px;
  margin-left: 4px;
}

.indicator-mini .change {
  font-size: 12px;
}

.indicator-mini .change.positive {
  color: #ff4d4f;
}

.indicator-mini .change.negative {
  color: #52c41a;
}

.text-danger {
  color: #ff4d4f !important;
}

.trend-chart-placeholder {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  padding: 20px;
  min-height: 200px;
}

.trend-chart {
  width: 100%;
  height: 200px;
}

.chart-mock {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #8b9dc3;
  font-size: 18px;
}

.loading-spinner {
  color: #00d7e9;
  font-size: 16px;
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.error-message {
  color: #ff4d4f;
  font-size: 14px;
  text-align: center;
  padding: 20px;
}

/* 仪表盘 */
.card-body-center {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 300px;
}

.gauge-container {
  text-align: center;
}

.gauge-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

/* 逾期指标容器 */
.overdue-indicators {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 100%;
  padding: 10px 0;
}

.overdue-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

.overdue-gauge {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gauge-value {
  font-size: 36px;
  font-weight: bold;
  margin-bottom: 5px;
}

.gauge-value.gauge-danger {
  color: #ff4d4f;
}

.gauge-value.gauge-warning {
  color: #faad14;
}

.gauge-value.gauge-safe {
  color: #52c41a;
}

.gauge-value .unit {
  font-size: 18px;
  margin-left: 3px;
}

.overdue-label {
  text-align: center;
}

.label-title {
  color: #8b9dc3;
  font-size: 13px;
  margin-bottom: 5px;
  font-weight: 500;
}

.label-desc {
  font-size: 14px;
  font-weight: 500;
}

.label-desc.gauge-danger {
  color: #ff4d4f;
}

.label-desc.gauge-warning {
  color: #faad14;
}

.label-desc.gauge-safe {
  color: #52c41a;
}

/* 第二行：风险源下钻地图（全宽） */
.section-risk-map {
  width: 100%;
}

/* 第三行：未来风险预警（全宽） */
.section-warning {
  width: 100%;
}

.warning-row {
  display: flex;
  gap: 20px;
}

.warning-chart-card {
  flex: 1;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  padding: 20px;
  border: 1px solid rgba(0, 215, 233, 0.2);
}

/* 选项卡 */
.tabs-container {
  margin-top: 10px;
}

.tabs-nav {
  display: flex;
  gap: 5px;
  border-bottom: 2px solid rgba(0, 215, 233, 0.2);
  margin-bottom: 20px;
}

.tab-btn {
  background: transparent;
  border: none;
  color: #8b9dc3;
  padding: 10px 20px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
}

.tab-btn:hover {
  color: #00d7e9;
}

.tab-btn.active {
  color: #00d7e9;
  border-bottom-color: #00d7e9;
}

.tab-content {
  /* 不设置固定高度，自适应内容 */
}

.tab-pane {
  animation: fadeIn 0.3s;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* 矩形树图 */
.treemap-container {
  width: 100%;
  min-height: 500px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}

.treemap-placeholder {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  padding: 20px;
  /* 移除固定高度，自适应内容 */
}

.treemap-mock {
  /* 移除固定高度 */
}

.treemap-title {
  color: #8b9dc3;
  font-size: 16px;
  margin-bottom: 15px;
  text-align: center;
}

.treemap-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  min-height: 400px; /* 设置最小高度，实际高度由内容决定 */
  margin-bottom: 15px;
}

.treemap-item {
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 10px;
  color: #fff;
  font-weight: 500;
  transition: all 0.3s;
  cursor: pointer;
}

.treemap-item:hover {
  transform: scale(1.02);
  box-shadow: 0 0 15px rgba(0, 215, 233, 0.5);
}

.treemap-legend {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-top: 10px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  color: #8b9dc3;
  font-size: 12px;
}

.dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

.dot-danger {
  background: rgba(255, 77, 79, 0.8);
}

.dot-warning {
  background: rgba(250, 173, 20, 0.8);
}

.dot-safe {
  background: rgba(82, 196, 26, 0.8);
}

/* 预警图表 */
.warning-chart,
.warning-chart-card {
  margin-bottom: 0;
}

.chart-title {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 15px;
}

.chart-title span:first-child {
  color: #00d7e9;
  font-size: 16px;
  font-weight: 500;
}

.chart-subtitle {
  color: #8b9dc3;
  font-size: 12px;
}

.chart-value {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 15px;
}

.value-large {
  color: #fff;
  font-size: 32px;
  font-weight: bold;
}

.value-large .unit {
  font-size: 16px;
  margin-left: 4px;
}

.value-change {
  font-size: 14px;
}

.value-change.positive {
  color: #ff4d4f;
}

.value-change.negative {
  color: #52c41a;
}

.mini-chart-placeholder {
  width: 100%;
  height: 120px;
}

.mini-chart {
  width: 100%;
  height: 100%;
}

.mini-chart-placeholder {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  padding: 15px;
  min-height: 120px;
}

.mini-chart-mock {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  color: #8b9dc3;
  font-size: 14px;
}

.divider {
  height: 1px;
  background: rgba(0, 215, 233, 0.2);
  margin: 30px 0;
}

/* 第三行：根源诊断 */
.vintage-analysis {
  padding: 10px 0;
}

.chart-area-large {
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  padding: 30px;
  min-height: 400px;
}

.vintage-chart-placeholder {
  height: 100%;
}

.vintage-chart-mock .chart-title {
  color: #8b9dc3;
  font-size: 16px;
  text-align: center;
  margin-bottom: 30px;
}

.bar-chart-mock {
  margin-bottom: 30px;
}

.chart-bars {
  display: flex;
  justify-content: space-around;
  align-items: flex-end;
  height: 250px;
  padding: 0 50px;
}

.bar-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  flex: 1;
}

.bar {
  width: 80px;
  background: linear-gradient(180deg, #ff4d4f 0%, #ff7875 100%);
  border-radius: 4px 4px 0 0;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-top: 10px;
  transition: all 0.3s;
  cursor: pointer;
}

.bar:hover {
  filter: brightness(1.2);
  transform: scaleY(1.05);
}

.bar-label {
  color: #fff;
  font-size: 14px;
  font-weight: bold;
}

.bar-xlabel {
  color: #8b9dc3;
  font-size: 14px;
}

.chart-insight {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(0, 215, 233, 0.1);
  border-left: 3px solid #00d7e9;
  padding: 15px 20px;
  border-radius: 4px;
}

.insight-icon {
  font-size: 24px;
}

.insight-text {
  color: #00d7e9;
  font-size: 14px;
  line-height: 1.6;
}

/* 账龄分析图表 */
.vintage-chart {
  width: 100%;
  height: 400px;
  margin-bottom: 20px;
}

.chart-insight {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(0, 215, 233, 0.1);
  border-left: 3px solid #00d7e9;
  padding: 15px 20px;
  border-radius: 4px;
  margin-top: 20px;
}

.chart-insight .insight-icon {
  font-size: 24px;
}

.chart-insight .insight-text {
  color: #00d7e9;
  font-size: 14px;
  line-height: 1.6;
}

/* 前十大不良贷款户 */
.section-top-customers {
  width: 100%;
}

.top-customers-content {
  min-height: 500px;
  position: relative;
}

.loading-container,
.empty-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 500px;
  color: #8b9dc3;
}

.empty-message {
  font-size: 16px;
}

/* 客户详情弹窗 */
.detail-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
  animation: fadeIn 0.3s;
}

.detail-dialog {
  background: linear-gradient(135deg, #061e5d 0%, #0a2b6b 100%);
  border: 2px solid rgba(0, 215, 233, 0.5);
  border-radius: 8px;
  width: 90%;
  max-width: 900px;
  max-height: 80vh;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 215, 233, 0.3);
  display: flex;
  flex-direction: column;
}

.dialog-header {
  padding: 20px 30px;
  border-bottom: 1px solid rgba(0, 215, 233, 0.3);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: rgba(0, 215, 233, 0.05);
}

.dialog-header h3 {
  color: #00d7e9;
  font-size: 18px;
  margin: 0;
  font-weight: 600;
}

.close-btn {
  background: transparent;
  border: none;
  color: #8b9dc3;
  font-size: 24px;
  cursor: pointer;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.3s;
}

.close-btn:hover {
  background: rgba(255, 77, 79, 0.2);
  color: #ff4d4f;
}

.dialog-body {
  padding: 25px 30px;
  overflow-y: auto;
  flex: 1;
}

.customer-summary {
  display: flex;
  gap: 40px;
  margin-bottom: 25px;
  padding: 20px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  border: 1px solid rgba(0, 215, 233, 0.2);
}

.summary-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.summary-item .label {
  color: #8b9dc3;
  font-size: 13px;
}

.summary-item .value {
  color: #fff;
  font-size: 20px;
  font-weight: bold;
}

.loans-table {
  width: 100%;
  overflow-x: auto;
}

.loans-table table {
  width: 100%;
  border-collapse: collapse;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  overflow: hidden;
}

.loans-table thead {
  background: rgba(0, 215, 233, 0.1);
}

.loans-table th {
  padding: 12px 15px;
  text-align: left;
  color: #00d7e9;
  font-weight: 600;
  font-size: 13px;
  border-bottom: 2px solid rgba(0, 215, 233, 0.3);
}

.loans-table td {
  padding: 12px 15px;
  color: #fff;
  font-size: 13px;
  border-bottom: 1px solid rgba(139, 157, 195, 0.1);
}

.loans-table tbody tr:hover {
  background: rgba(0, 215, 233, 0.05);
}

.loans-table tbody tr:last-child td {
  border-bottom: none;
}

/* 表格文本对齐 */
.loans-table .text-right {
  text-align: right;
}

.loans-table .text-highlight {
  color: #00d7e9;
  font-weight: 500;
}

.loans-table .text-amount {
  color: #ff4d4f;
  font-weight: 600;
}

/* 风险等级徽章 */
.risk-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.risk-badge.risk-high {
  background: rgba(255, 77, 79, 0.2);
  color: #ff4d4f;
  border: 1px solid rgba(255, 77, 79, 0.5);
}

.risk-badge.risk-medium {
  background: rgba(250, 173, 20, 0.2);
  color: #faad14;
  border: 1px solid rgba(250, 173, 20, 0.5);
}

.risk-badge.risk-low {
  background: rgba(82, 196, 26, 0.2);
  color: #52c41a;
  border: 1px solid rgba(82, 196, 26, 0.5);
}

.risk-badge.risk-unknown {
  background: rgba(139, 157, 195, 0.2);
  color: #8b9dc3;
  border: 1px solid rgba(139, 157, 195, 0.5);
}

/* 表格水平滚动 */
.loans-table {
  overflow-x: auto;
  max-width: 100%;
}

.loans-table table {
  min-width: 1200px;
}

/* NPL动态排序图样式 */
.section-npl-race {
  width: 100%;
  margin-top: 20px;
}

.npl-race-content {
  min-height: 600px;
}

.tit-subtitle {
  margin-left: 10px;
  font-size: 12px;
  color: #8b9dc3;
  font-weight: normal;
}

.race-controls {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 15px 20px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  margin-bottom: 15px;
}

.race-btn {
  padding: 8px 16px;
  background: rgba(0, 215, 233, 0.2);
  border: 1px solid rgba(0, 215, 233, 0.5);
  color: #00d7e9;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s;
}

.race-btn:hover {
  background: rgba(0, 215, 233, 0.3);
  border-color: #00d7e9;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 215, 233, 0.3);
}

.race-btn:active {
  transform: translateY(0);
}

.race-speed {
  color: #8b9dc3;
  font-size: 13px;
  margin-left: auto;
}

.race-speed select {
  margin-left: 8px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(0, 215, 233, 0.3);
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
}

.race-speed select:focus {
  outline: none;
  border-color: #00d7e9;
}

.npl-race-chart {
  width: 100%;
  height: 600px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 4px;
}
</style>

